<script>
export default {
  render(c) {
    if (!this.errorMessage && this.ready) {
      // props
      const props = {
        button: this, // for more extensible
      };
      return c(this.buttonFullName, {
        staticClass: `tab-button ${this.showing ? '' : 'display-none'}`,
        props,
        on: {
          'buttonReal:ready': this.__onButtonRealReady,
          'buttonReal:destroy': this.__onButtonRealDestroy,
        },
        directives: [
          {
            name: 'eb-dragdrop',
            value: {
              scene: this.dragdropScene,
              button: this.options,
              onDragStart: this.onDragStart,
              onDropElement: this.onDropElement,
              onDragDone: this.onDragDone,
            },
          },
        ],
      });
    } else if (this.errorMessage) {
      return c('div', {
        staticClass: 'tab-button-inner tab-button-inner-error',
        domProps: { innerText: this.errorMessage },
      });
    }
    return c('div');
  },
  props: {
    layout: {
      type: Object,
    },
    group: {
      type: Object,
    },
    options: {
      type: Object,
    },
    dragdropScene: {
      type: String,
    },
  },
  data() {
    return {
      ready: false,
      errorMessage: null,
      showing: true,
    };
  },
  computed: {
    buttons() {
      return this.group.buttons;
    },
    buttonFullName() {
      return this.layout._buttonFullName(this.options);
    },
  },
  created() {
    this.__init();
  },
  beforeDestroy() {
    this.$emit('button:destroy');
  },
  methods: {
    async __init() {
      if (!this.options.resourceConfig) {
        // maybe disabled
        this.hide();
        return;
      }
      const module = await this.$meta.module.use(this.options.resourceConfig.module);
      const fullName = this.buttonFullName;
      let component = module.options.components[this.options.resourceConfig.component];
      if (!component) {
        this.errorMessage = `${this.$text('Button Not Found')}: ${fullName}`;
        this.ready = false;
      } else {
        // uses
        await this.$meta.util.createComponentOptionsUses(component);
        // create
        component = this.$meta.util.createComponentOptions(component);
        this.$options.components[fullName] = component;
        this.ready = true;
        this.errorMessage = null;
      }
    },
    show() {
      this.showing = true;
    },
    hide() {
      this.showing = false;
    },
    onDragStart({ $el, context, dragElement }) {
      const [button, buttonIndexDrag] = this.group._getButtonAndIndex(context.button);
      const tooltip = this.__getButtonTitle(button);
      return { tooltip };
    },
    onDropElement({ $el, context, dragElement, dragContext }) {
      const [buttonDrop, buttonIndexDrop] = this.group._getButtonAndIndex(context.button);
      const [buttonDrag, buttonIndexDrag] = this.group._getButtonAndIndex(dragContext.button);
      if (buttonIndexDrop === buttonIndexDrag || buttonIndexDrop == buttonIndexDrag + 1) return null;
      // dropElement
      const dropElement = $el;
      // tooltip
      const tooltip = this.__getButtonTitle(buttonDrop);
      // ok
      return { dropElement, tooltip };
    },
    onDragDone({ $el, context, dragElement, dropElement, dropContext }) {
      const buttonIndexDrag = this.group._getButtonIndex(context.button);
      this.group.buttons.splice(buttonIndexDrag, 1);
      const buttonIndexDrop = this.group._getButtonIndex(dropContext.button);
      this.group.buttons.splice(buttonIndexDrop, 0, context.button);
      // save
      this.layout.__saveLayoutConfig();
    },
    __getButtonTitle(button) {
      return button.titleLocale || this.$text(button.title) || button.name;
    },
    __onButtonRealReady(buttonReal) {
      const fullName = this.buttonFullName;
      this.group.buttonsReal[fullName] = buttonReal;
    },
    __onButtonRealDestroy(buttonReal) {
      const fullName = this.buttonFullName;
      delete this.group.buttonsReal[fullName];
    },
  },
};
</script>
